//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
//------------------------------------------------------------------------------
//
//  File: idle.c
//
//  This file contains OEMIdle function implementation. This implementation
//  is suitable for most hardware. It depends on timer which allows extend
//  and reduce actual tick period and it has input clock freq >= 1 kHz.
//  The OALCPUIdle is called to move CPU/SoC to low power mode. Separate file
//  contains busy loop implementation which can be used in developer process.
//  When hardware doesn't support low power mode it is preffered to stub
//  OEMIdle function compared to busy loop OALCPUIdle.
//
#include <windows.h>
#include <nkintr.h>
#include <oal.h>
 
// External Variables 
// Global Variables 

// Defines 

// Types
 
// Local Variables 
 
// Local Functions 


void OEMWriteDebugLEDFlashing(UINT32 time);


//------------------------------------------------------------------------------
//
//  Function:     OEMIdle
//
//  This function is called by the kernel when there are no threads ready to 
//  run. The CPU should be put into a reduced power mode if possible and halted. 
//  It is important to be able to resume execution quickly upon receiving an 
//  interrupt.
//
//  Interrupts are disabled when OEMIdle is called and when it returns.
//
//  Note that system timer must be running when CPU/SoC is moved to reduced
//  power mode.
//
void OEMIdle(DWORD idleParam)
{
    INT32 idleMSec;
    INT32 idleCounts;

    // Compute the remaining idle time
    idleMSec = (INT32)(dwReschedTime - CurMSec);

    if(idleMSec <= 0)
        goto cleanUp;

    // Move SoC/CPU to idle mode
    idleCounts = OALCPUIdle(idleMSec);

    g_oalTimer.idleCounts += idleCounts;


    // Direct use idlecounts to caculate idle timer
    // curridlehigh is not needed to update as iconv is set as 1
    // and GetIdleTime is DWORD - 32 bit level
    // although idleCounts*125 could overflow, its result is 64-bit and still
    // can keep enough bits for shifting to a 32-bit curridlelow.
    curridlelow = (UINT32)((g_oalTimer.idleCounts* 125) >> 12);

cleanUp:
    return;

    //NKDbgPrintfW(TEXT("-\r\n"));
}

//------------------------------------------------------------------------------

